package com.tangdi.production.mpaychl.service.impl.xinjianyi;

import java.math.BigInteger;
import java.security.MessageDigest;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.tangdi.production.mpaychl.base.service.BaseTranService;
import com.tangdi.production.mpaychl.dao.EasyConfigMapper;
import com.tangdi.production.mpaychl.model.EasyConfig;
import com.tangdi.production.mpbase.constants.MsgCT;
import com.tangdi.production.mpbase.exception.TranException;
import com.tangdi.production.mpbase.util.HttpUtil;
import com.tangdi.production.mpbase.util.MoneyUtils;
import com.tangdi.production.mpbase.util.ObjectUtil;

@Service("QUICY_Easypay")
public class EasyServiceImpl implements BaseTranService {
	private static final Logger logger = LoggerFactory.getLogger(EasyServiceImpl.class);
	
	private static final String PayUrlPrefix = "https://pay.ipay.kim/cashier/Home";//支付请求地址
	
	private static final String notify_url = "http://ce.imbitpay.com:8083/mpcctp/easypay/{0}/payCallBack.json";
	
	private static final Map<String, Integer> recordTable = new Hashtable<String, Integer>();
	
	@Autowired
	private EasyConfigMapper easyConfigMapper;
	
	@Override
	public Map<String, Object> execute(Map<String, Object> param) throws TranException {
		logger.info("进入自有跳转EasyPay处理接口 [{}]", param);
		
		String reqData = "" + param.get("reqData");
		JSONObject reqDataJSONObject = JSON.parseObject(reqData);
		String orgNo = reqDataJSONObject.getString("orgNo");
		
		List<EasyConfig> easyConfigList = easyConfigMapper.selectByLimit(StringUtils.isBlank(orgNo) ? "1" : orgNo);
		EasyConfig easyConfig = null;
		if (easyConfigList != null && easyConfigList.size() > 0){
//			easyConfig = easyConfigList.get(RandomUtils.nextInt(0, easyConfigList.size()));
			
			// 轮训
			logger.info("当前轮训总览:{}", JSON.toJSONString(recordTable));
			Integer nowKey = recordTable.get(orgNo) == null ? -1 : recordTable.get(orgNo);
			Integer nextKey = easyConfigList.size()-1 > nowKey ? nowKey + 1 : 0;
			logger.info("机构号:{},当前轮训值:{}", orgNo, nextKey);
			recordTable.put(orgNo, nextKey);
			
			easyConfig = easyConfigList.get(nextKey);
			logger.info("获取通道信息:{}", easyConfig.getId() + "|" + easyConfig.getMchKey());
			
			EasyConfig record = new EasyConfig();
			record.setId(easyConfig.getId());
			record.setUseNum(easyConfig.getUseNum() + 1);
			record.setUseAmt(easyConfig.getUseAmt() + Long.valueOf("" + param.get("ordamt")));
			record.setUpdDttm(DateFormatUtils.format(new Date(), "yyyyMMddHHmmss"));
			easyConfigMapper.updateByPrimaryKeySelective(record);
		}
		
		if (easyConfig == null){
			logger.error("没找到可用的支付通道,orgNo={}", orgNo);
			throw new TranException("08020001","交易异常，没找到可用的支付通道");
		}
		
  		ArrayList<KeyValuePair> list = new ArrayList<KeyValuePair>();
  		list.add(new KeyValuePair("mch_id", easyConfig.getMchId()));//测试商户号
  		list.add(new KeyValuePair("out_trade_no", "" + param.get("prdOrdNo")));//商户订单号
  		list.add(new KeyValuePair("callback_url", (String)param.get("frontUrl")));//同步回调地址
  		list.add(new KeyValuePair("notify_url", MessageFormat.format(notify_url, easyConfig.getId())));//异步通知地址
  		
		String payAmt = ObjectUtil.getString(param.get("payAmt"));
		logger.info("支付金额[{}分]", payAmt);
		payAmt = MoneyUtils.toStrYuan(payAmt);
		logger.info("支付金额转换为元[{}]", payAmt);
  		list.add(new KeyValuePair("total_fee", payAmt));//交易金额
  		
  		/*
	  	  wx:微信
	  	  al:支付宝
	  	  qq:qq钱包（最小金额10元）
	  	  jd:京东
	  	  wy:网银支付
	  	  kj:快捷支付（最小金额10元）
	  	  yl:银联二维码（最小金额10元）
	  	  说明：其中微信wx接口类型h5为way=wap，其中支付宝al接口类型h5为way=pay
  	 */
  		list.add(new KeyValuePair("service", "kj"));//接口类型
  		/*
	  	  h5：公众号支付或者其他js支付
	  	  pay：扫码
	  	  micropay：被扫支付
	  	  wap：wap支付或者网关支付
	  	  app:app支付
  	    */
  		list.add(new KeyValuePair("way", "wap"));//支付方式
  		list.add(new KeyValuePair("format", "json"));//返回数据格式
        // 组织签名数据
  		String sign = "";
  		for (KeyValuePair p : list)
  		{
  			sign+=p.Zhi;
  		}
  		
        list.add(new KeyValuePair("sign", getMD5(sign + easyConfig.getMchKey())));//签名
        list.add(new KeyValuePair("mch_create_ip", "154.48.237.13"));//请求客户的ip微信支付必传
        list.add(new KeyValuePair("sub_appid", ""));//没有应用时可以不传此参数
        list.add(new KeyValuePair("sub_openid", ""));//用户的openid公众号支付时必须填写
        list.add(new KeyValuePair("goods_tag", "ABC"));//除网银其他支付可不传
        list.add(new KeyValuePair("body", "" + param.get("prdOrdNo")));//必传
        // 拼接请求链接
        StringBuilder payUrl = new StringBuilder();
        payUrl.append(PayUrlPrefix).append("?");
        for (KeyValuePair p : list)
  		{
		    payUrl.append(p.Jian).append("=").append(p.Zhi).append("&");
  		}
        String url = payUrl.substring(0, payUrl.length() - 1);
        
        logger.info("请求参数:{}", url);//打印请求链接
        try {
			String content = HttpUtil.httpRequest(url, "GET");
			logger.info("返回[{}]", content);
			
			JSONObject resJson = JSON.parseObject(content);
			if (!resJson.getBoolean("success")){
				Map<String,Object> backMap = new HashMap<>();
				backMap.put("ordStatus", MsgCT.ORDSTATUS_FAIL);
				backMap.put("msg", "调用newEasy支付通道失败:" + resJson.get("msg"));
				return backMap;
			}
			Map<String,Object> backMap = new HashMap<>();
			backMap.put("ordStatus", MsgCT.ORDSTATUS_PROCESSING);
			backMap.put("contentType", MsgCT.DATA_TYPE_JSON);
			backMap.put("busContent", resJson.get("pay_info"));
			return backMap;
		} catch (Exception e) {
			logger.error("Easy-Pay调用支付通道异常:{}", e.getMessage(), e);
			Map<String,Object> backMap = new HashMap<>();
			backMap.put("ordStatus", MsgCT.ORDSTATUS_FAIL);
			backMap.put("msg", "调用newEasy支付通道异常:" + e.getMessage());
			return backMap;
		}
	}

    public static String getMD5(String str) {
        try {
            // 生成一个MD5加密计算摘要
            MessageDigest md = MessageDigest.getInstance("MD5");
            // 计算md5函数
            md.update(str.getBytes());
            // digest()最后确定返回md5 hash值，返回值为8为字符串。因为md5 hash值是16位的hex值，实际上就是8位的字符
            // BigInteger函数则将8位的字符串转换成16位hex值，用字符串来表示；得到字符串形式的hash值
            String md5=new BigInteger(1, md.digest()).toString(16);
            //BigInteger会把0省略掉，需补全至32位
            return fillMD5(md5);
        } catch (Exception e) {
            throw new RuntimeException("MD5加密错误:"+e.getMessage(),e);
        }
    }
    
    public static String fillMD5(String md5){
        return md5.length()==32?md5:fillMD5("0"+md5);
    }
    
}

class KeyValuePair {
	public String Jian;
    public String Zhi;
 
    public KeyValuePair(String k, String v)
    {
        Jian = k;
        Zhi = v;
    }
}